跳到主要内容

04. JSON

Pydantic 提供了内置的 JSON 解析支持

  • 有着比其他第三方库更优秀的解析性能
  • 支持自定义错误
  • 支持严格规范(strict specifications)

使用严格规范解析的例子 👇

from datetime import date

from pydantic import BaseModel, ConfigDict, ValidationError


class Event(BaseModel):
model_config = ConfigDict(strict=True)

when: date
where: tuple[int, int]


json_data = '{"when": "1987-01-28", "where": [51, -1]}'
print(Event.model_validate_json(json_data))
#> when=datetime.date(1987, 1, 28) where=(51, -1)

try:
Event.model_validate({'when': '1987-01-28', 'where': [51, -1]})
except ValidationError as e:
print(e)
"""
2 validation errors for Event
when
Input should be a valid date [type=date_type, input_value='1987-01-28', input_type=str]
where
Input should be a valid tuple [type=tuple_type, input_value=[51, -1], input_type=list]
"""

不完整的 JSON 解析

v2.7.0 后,Pydantic 支持了残缺 JSON 解析功能,用这个 api:pydantic_core.from_json

from pydantic_core import from_json

partial_json_data = '["aa", "bb", "c'

try:
result = from_json(partial_json_data, allow_partial=False)
except ValueError as e:
print(e)
#> EOF while parsing a string at line 1 column 15

result = from_json(partial_json_data, allow_partial=True)
print(result)
#> ['aa', 'bb']
type(result)
#> list

列表、字典都适用

from pydantic_core import from_json

partial_dog_json = '{"breed": "lab", "name": "fluffy", "friends": ["buddy", "spot", "rufus"], "age'
dog_dict = from_json(partial_dog_json, allow_partial=True)
print(dog_dict)
#> {'breed': 'lab', 'name': 'fluffy', 'friends': ['buddy', 'spot', 'rufus']}

In future versions of Pydantic, we expect to expand support for this feature through either Pydantic's other JSON validation functions (pydantic.main.BaseModel.model_validate_json and pydantic.type_adapter.TypeAdapter.validate_json) or model configuration. Stay tuned 🚀!

可以将 from_jsonmodel_validate 合用

from pydantic_core import from_json

from pydantic import BaseModel


class Dog(BaseModel):
breed: str
name: str
friends: list


partial_dog_json = '{"breed": "lab", "name": "fluffy", "friends": ["buddy", "spot", "rufus"], "age'
dog = Dog.model_validate(from_json(partial_dog_json, allow_partial=True))
print(repr(dog))
#> Dog(breed='lab', name='fluffy', friends=['buddy', 'spot', 'rufus'])

For partial JSON parsing to work reliably, all fields on the model should have default values.